package com.yueyang.sojourn.server.controller.wx;

import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.bean.result.BaseWxPayResult;
import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryResult;
import com.github.binarywang.wxpay.bean.result.WxPayRefundQueryResult;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.ProfitSharingService;
import com.github.binarywang.wxpay.service.WxPayService;
import com.yueyang.sojourn.server.common.LoginNeedless;
import com.yueyang.sojourn.server.controller.BaseController;
import com.yueyang.sojourn.server.controller.model.JsonResult;
import com.yueyang.sojourn.server.model.enums.OrderStatusEnum;
import com.yueyang.sojourn.server.model.enums.PayConstants;
import com.yueyang.sojourn.server.model.po.SojournMerch;
import com.yueyang.sojourn.server.model.po.SojournOrder;
import com.yueyang.sojourn.server.model.po.SojournOrderRefund;
import com.yueyang.sojourn.server.model.po.SojournTransaction;
import com.yueyang.sojourn.server.model.vo.SojournWxPayPrepayVo;
import com.yueyang.sojourn.server.service.sojourn.merch.SojournMerchService;
import com.yueyang.sojourn.server.service.sojourn.order.SojournOrderRefundService;
import com.yueyang.sojourn.server.service.sojourn.order.SojournOrderService;
import com.yueyang.sojourn.server.service.sojourn.pay.PayServiceWill;
import com.yueyang.sojourn.server.service.sojourn.transaction.SojournTransactionService;
import com.yueyang.sojourn.server.utils.IpUtil;
import com.yueyang.uc.model.UcLoginUserV1;
import com.yueyang.uc.model.UcUserV1;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Date;

/**
 * @author Andy.yang
 * @version v1
 * @summary
 * @Copyright (c) 2019, yueyang Group All Rights Reserved.
 * @since 2020/3/6
 */

@Slf4j
@RestController
@RequestMapping("/api/wx/order/pay")
@Api(tags = "(小程序)订单支付 API")
public class ApiPayControllerWill extends BaseController {
    @Autowired
    private WxPayService wxPayService;
    @Autowired
    private SojournOrderService orderService;
    @Autowired
    private SojournMerchService merchService;
    @Autowired
    private SojournTransactionService transactionService;
    @Autowired
    private PayServiceWill payService;
    @Autowired
    private SojournOrderRefundService orderRefundService;


    @ApiImplicitParam(name = "X-Token", paramType = "header", required = true)
    @ApiOperation(value = "微信支付预付定单")
    @GetMapping("/prepay")
    public JsonResult<SojournWxPayPrepayVo> prepay(@ApiParam(value = "订单id")
                             @RequestParam(value = "orderId") Long orderId,
                                                   @ApiParam(value = "app类型：1-小程序；2-H5") @RequestParam(value = "appType")Integer appType,
                                                   HttpServletRequest request) {
        UcLoginUserV1 loginUser = getLoginUser();
        if(orderId == null || orderId <= 0){
            return fail("订单id不能为空");
        }
        SojournOrder order = orderService.findById(orderId);
        if(order == null){
            return fail("订单不存在");
        }
        if(OrderStatusEnum.TO_BE_PAY.getCode() != order.getStatus()){
            return fail("订单状态错误，无法支付");
        }
        if(order.getPayEndTime().before(new Date())){
            return fail("订单已过期");
        }
        SojournMerch merch = merchService.selectByPrimaryKey(order.getMerchId());
        if(merch == null){
            return fail("商品不存在");
        }
        String ip = IpUtil.getIpAddr(request);
        try {
            WxPayMpOrderResult result = payService.prepay(orderId, ip, true, loginUser);
            SojournWxPayPrepayVo vo = new SojournWxPayPrepayVo();
            BeanUtils.copyProperties(result,vo);
            JsonResult rs = ok();
            rs.setData(vo);
            return rs;
        }catch (Exception e){
            e.printStackTrace();
            log.error(e.getMessage(),e);
            return fail("系统开小差了，请稍后再试");
        }
    }


    /**
     * 微信付款成功或失败回调接口
     * <p>
     *  TODO
     *  注意，这里pay-notify是示例地址，建议开发者应该设立一个隐蔽的回调地址
     *
     * @param request 请求内容
     * @return 操作结果
     */
    @LoginNeedless
    @PostMapping("/pay-notify")
    public Object payNotify(HttpServletRequest request) {
        log.error("支付结果回调通知开始================");
        String xmlResult = null;
        try {
            xmlResult = IOUtils.toString(request.getInputStream(), request.getCharacterEncoding());
        } catch (IOException e) {
            e.printStackTrace();
            return fail(e.getMessage());
        }
        log.info("支付结果回调通知--参数：" + xmlResult);
        WxPayOrderNotifyResult result = null;
        try {
            result = wxPayService.parseOrderNotifyResult(xmlResult);

            if(!WxPayConstants.ResultCode.SUCCESS.equals(result.getResultCode())){
//                logger.error(xmlResult);
                throw new WxPayException("微信通知支付失败！");
            }
            if(!WxPayConstants.ResultCode.SUCCESS.equals(result.getReturnCode())){
//                logger.error(xmlResult);
                throw new WxPayException("微信通知支付失败！");
            }
        } catch (WxPayException e) {
            e.printStackTrace();
            return fail(e.getMessage());
        }

//        logger.info("处理腾讯支付平台的订单支付");
//        logger.info(result);

        String orderSn = result.getOutTradeNo();
        String payId = result.getTransactionId();

        // 分转化成元
        String totalFee = BaseWxPayResult.fenToYuan(result.getTotalFee());
        System.out.println("totalFee=" + totalFee);

        WxPayOrderQueryResult rs = new WxPayOrderQueryResult();
        rs.setTransactionId(result.getTransactionId());  //todo 临时处理
        payService.paid(rs);
        return WxPayNotifyResponse.success("处理成功!");
    }


//
//    @ApiOperation(value = "关闭wx订单")
//    @LoginNeedless
//    @GetMapping("/closeOrder")
//    public JsonResult closeOrder(@ApiParam(value = "订单id") @RequestParam Long orderId, HttpServletRequest request) {
//        String openId = "o7S1I4xYpbj7jzAzjqwwH__z7GXs";
//        try {
//            SojournOrder order = orderService.findById(orderId);
//            WxPayOrderCloseResult result = wxPayService.closeOrder(order.getSn());
//            JsonResult ok = ok();
//            ok.setData(result);
//            return ok;
//        } catch (WxPayException e) {
//            e.printStackTrace();
//            return fail(e.getMessage());
//        }
//    }
//
//    /**
//     * 微信退款成功或失败回调接口
//     * <p>
//     *  TODO
//     *  注意，这里pay-notify是示例地址，建议开发者应该设立一个隐蔽的回调地址
//     *
//     * @param request 请求内容
//     * @return 操作结果
//     */
//    @LoginNeedless
//    @PostMapping("refund-notify")
//    public Object refundNotify(HttpServletRequest request) {
//        String xmlResult = null;
//        try {
//            xmlResult = IOUtils.toString(request.getInputStream(), request.getCharacterEncoding());
//        } catch (IOException e) {
//            e.printStackTrace();
//            return fail(e.getMessage());
//        }
//
//        WxPayRefundNotifyResult result = null;
//        try {
//            result = wxPayService.parseRefundNotifyResult(xmlResult);
//
//            if(!WxPayConstants.ResultCode.SUCCESS.equals(result.getResultCode())){
////                logger.error(xmlResult);
//                throw new WxPayException("微信通知退款失败！");
//            }
//            if(!WxPayConstants.ResultCode.SUCCESS.equals(result.getReturnCode())){
////                logger.error(xmlResult);
//                throw new WxPayException("微信通知退款失败！");
//            }
//        } catch (WxPayException e) {
//            e.printStackTrace();
//            return fail(e.getMessage());
//        }
//
////        logger.info("处理腾讯支付平台的订单支付");
////        logger.info(result);
//
//        String returnMsg = result.getReturnMsg();
//        return WxPayNotifyResponse.success("处理成功!");
//    }
//
//    @ApiOperation(value = "查询wx订单状态")
//    @LoginNeedless
//    @GetMapping("/queryWxOrder")
//    public JsonResult queryWxOrder(@ApiParam(value = "订单id") @RequestParam Long orderId, HttpServletRequest request) {
//        String openId = "o7S1I4xYpbj7jzAzjqwwH__z7GXs";
//        try {
//            SojournOrder order = orderService.findById(orderId);
//            WxPayOrderQueryResult result = wxPayService.queryOrder(null,order.getSn());
//            JsonResult ok = ok();
//            ok.setData(result);
//            return ok;
//        } catch (WxPayException e) {
//            e.printStackTrace();
//            return fail(e.getMessage());
//        }
//    }
//
    @ApiImplicitParam(name = "X-Token", paramType = "header", required = true)
    @ApiOperation(value = "申请退款")
    @GetMapping("/refund")
    public JsonResult refund(@ApiParam(value = "退款单id") @RequestParam Long refundId, HttpServletRequest request) {
        try {
            WxPayRefundResult result = payService.refund(refundId,getLoginUser());
            JsonResult ok = ok();
            ok.setData(result);
            return ok;
        } catch (Exception e) {
            e.printStackTrace();
            return fail(e.getMessage());
        }
    }

    @ApiImplicitParam(name = "X-Token", paramType = "header", required = true)
    @ApiOperation(value = "通过订单申请退款--测试用")
    @GetMapping("/refund/order")
    public JsonResult refundOrder(@ApiParam(value = "订单id") @RequestParam Long orderId, HttpServletRequest request) {
        try {
            SojournOrder order = orderService.findById(orderId);
            if(order == null){
                return fail("订单不存在");
            }
            SojournOrderRefund refund = orderRefundService.findByOrderId(orderId);
            if(refund == null){
                refund = new SojournOrderRefund();
                refund.setOrderType(order.getType());
                refund.setTotalFee(order.getTotalPrice());
                refund.setCreator(-1L);
                refund.setOrderId(orderId);
                refund.setReason("不想去了");
                refund.setThirdRefunded(0);
                orderRefundService.add(refund);
            }
            WxPayRefundResult result = payService.refund(refund.getId(),getLoginUser());
            JsonResult ok = ok();
            ok.setData(result);
            return ok;
        } catch (Exception e) {
            e.printStackTrace();
            return fail(e.getMessage());
        }
    }

    @ApiImplicitParam(name = "X-Token", paramType = "header", required = true)
    @ApiOperation(value = "微信支付成功回调同步订单状态")
    @PutMapping("/paid/result")
    public void payResultUpdateOrderStatus(@ApiParam(value = "订单id") @RequestParam(value = "orderId") Long orderId) {
        try {
            SojournOrder order = orderService.findById(orderId);
            if(order == null){
                return;
            }

            SojournTransaction transaction = transactionService.findPayByOrderSn(order.getSn());
            if(transaction == null || PayConstants.TransactionStatusEnum.PAYING.getCode() != transaction.getStatus()){
                return;
            }

            WxPayOrderQueryResult orderPayRs = payService.queryOrder(transaction);
            payService.paid(orderPayRs);
        } catch (Exception e) {
            log.error(e.getMessage(),e);
        }
    }

//
//    @ApiOperation(value = "查询退款")
//    @LoginNeedless
//    @GetMapping("/refundQuery")
//    public JsonResult refundQuery(@ApiParam(value = "订单id") @RequestParam Long orderId, HttpServletRequest request) {
//        String openId = "o7S1I4xYpbj7jzAzjqwwH__z7GXs";
//        try {
//            String myRfId = "rf" + orderId.toString();
//            WxPayRefundQueryResult result = wxPayService.refundQuery(null,null,myRfId,null);
//            JsonResult ok = ok();
//            ok.setData(result);
//            return ok;
//        } catch (WxPayException e) {
//            e.printStackTrace();
//            return fail(e.getMessage());
//        }
//    }
//
//    @ApiOperation(value = "下载对账单")
//    @LoginNeedless
//    @GetMapping("/downloadbill")
//    public JsonResult downloadbill(@ApiParam(value = "账单日期") @RequestParam String date, HttpServletRequest request) {
//        String openId = "o7S1I4xYpbj7jzAzjqwwH__z7GXs";
//        try {
//            WxPayBillResult result = wxPayService.downloadBill(date, WxPayConstants.BillType.ALL,null,null);
//            JsonResult ok = ok();
//            ok.setData(result);
//            return ok;
//        } catch (WxPayException e) {
//            e.printStackTrace();
//            return fail(e.getMessage());
//        }
//    }
//
//    @ApiOperation(value = "下载资金账单")
//    @LoginNeedless
//    @GetMapping("/downloadFundFlow")
//    public JsonResult downloadfundflow(@ApiParam(value = "账单日期") @RequestParam String date, HttpServletRequest request) {
//        String openId = "o7S1I4xYpbj7jzAzjqwwH__z7GXs";
//        try {
//            WxPayFundFlowResult result = wxPayService.downloadFundFlow(date, WxPayConstants.AccountType.BASIC,null);
//            JsonResult ok = ok();
//            ok.setData(result);
//            return ok;
//        } catch (WxPayException e) {
//            e.printStackTrace();
//            return fail(e.getMessage());
//        }
//    }
//
//
//    //-------------------------------- 分账
//
//    @ApiImplicitParam(name = "X-Token", paramType = "header", required = true)
//    @ApiOperation(value = "增加分账方")
//    @GetMapping("/addReceiver")
//    public JsonResult addReceiver(@ApiParam(value = "订单id") @RequestParam Long orderId,
//                             @ApiParam(value = "app类型：1-小程序；2-H5") @RequestParam Integer appType,
//                             HttpServletRequest request) throws WxPayException {
//        payService.addWxPlatformShareReceiver("1581495641");
//        return ok();
//    }
//
//    @ApiOperation(value = "完结分账")
//    @GetMapping("/finsh")
//    public JsonResult finsh(@ApiParam(value = "订单id") @RequestParam Long transId,
//                                  @ApiParam(value = "app类型：1-小程序；2-H5") @RequestParam Integer appType,
//                                  HttpServletRequest request) throws WxPayException {
//        payService.submitShare(transId.toString());
//        return ok();
//    }
//
//    @ApiOperation(value = "完结分账")
//    @GetMapping("/finshFind")
//    public JsonResult finshFind(@ApiParam(value = "订单id") @RequestParam Long transId,
//                            @ApiParam(value = "app类型：1-小程序；2-H5") @RequestParam Integer appType,
//                            HttpServletRequest request) throws WxPayException {
//        payService.queryFinish(transId.toString());
//        return ok();
//    }

}
